home *** CD-ROM | disk | FTP | other *** search
/ Windows 95 API Bible / Windows 95 API Bible 3 Disc Set.iso / Win32 API Bible Book 3 of 3.iso / chapte21 / frame.c < prev    next >
C/C++ Source or Header  |  1996-04-29  |  16KB  |  589 lines

  1.  
  2. #include <windows.h>
  3. #include <stdio.h>
  4. #include "Frame.h"
  5. #include <vfw.h>
  6.  
  7.  
  8. #if defined (WIN32)
  9.     #define IS_WIN32 TRUE
  10. #else
  11.     #define IS_WIN32 FALSE
  12. #endif
  13.  
  14. #define IS_NT      IS_WIN32 && (BOOL)(GetVersion() < 0x80000000)
  15. #define IS_WIN32S  IS_WIN32 && (BOOL)(!(IS_NT) && (LOBYTE(LOWORD(GetVersion()))<4))
  16. #define IS_WIN95   (BOOL)(!(IS_NT) && !(IS_WIN32S)) && IS_WIN32
  17.  
  18.  
  19.  
  20. HINSTANCE hInst;   // current instance
  21.  
  22. LPCTSTR lpszAppName = "MyApp";
  23. LPCTSTR lpszTitle   = "My Application"; 
  24.  
  25. // the rest of the stuff
  26. //......................
  27.  
  28. BOOL RegisterWin95( CONST WNDCLASS* lpwc );
  29.  
  30.  
  31. int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
  32.                       LPTSTR lpCmdLine, int nCmdShow)
  33. {
  34.    MSG      msg;
  35.    HWND     hWnd; 
  36.    WNDCLASS wc;
  37.  
  38.    wc.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
  39.    wc.lpfnWndProc   = (WNDPROC)WndProc;       
  40.    wc.cbClsExtra    = 0;                      
  41.    wc.cbWndExtra    = 0;                      
  42.    wc.hInstance     = hInstance;              
  43.    wc.hIcon         = LoadIcon (hInstance, lpszAppName); 
  44.    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  45.    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  46.    wc.lpszMenuName  = lpszAppName;              
  47.    wc.lpszClassName = lpszAppName;              
  48.  
  49.    if ( IS_WIN95 )
  50.    {
  51.       if ( !RegisterWin95( &wc ) )
  52.          return( FALSE );
  53.    }
  54.    else if ( !RegisterClass( &wc ) )
  55.       return( FALSE );
  56.  
  57.    hInst = hInstance; 
  58.  
  59.    hWnd = CreateWindow( lpszAppName, 
  60.                         lpszTitle,    
  61.                         WS_OVERLAPPEDWINDOW, 
  62.                         CW_USEDEFAULT, 0, 
  63.                         CW_USEDEFAULT, 0,  
  64.                         NULL,              
  65.                         NULL,              
  66.                         hInstance,         
  67.                         NULL               
  68.                       );
  69.  
  70.    if ( !hWnd ) 
  71.       return( FALSE );
  72.  
  73.    ShowWindow( hWnd, nCmdShow ); 
  74.    UpdateWindow( hWnd );         
  75.  
  76.    while( GetMessage( &msg, NULL, 0, 0) )   
  77.    {
  78.       TranslateMessage( &msg ); 
  79.       DispatchMessage( &msg );  
  80.    }
  81.  
  82.    return( msg.wParam ); 
  83. }
  84.  
  85.  
  86. BOOL RegisterWin95( CONST WNDCLASS* lpwc )
  87. {
  88.     WNDCLASSEX wcex;
  89.  
  90.    wcex.style         = lpwc->style;
  91.    wcex.lpfnWndProc   = lpwc->lpfnWndProc;
  92.    wcex.cbClsExtra    = lpwc->cbClsExtra;
  93.    wcex.cbWndExtra    = lpwc->cbWndExtra;
  94.    wcex.hInstance     = lpwc->hInstance;
  95.    wcex.hIcon         = lpwc->hIcon;
  96.    wcex.hCursor       = lpwc->hCursor;
  97.    wcex.hbrBackground = lpwc->hbrBackground;
  98.    wcex.lpszMenuName  = lpwc->lpszMenuName;
  99.    wcex.lpszClassName = lpwc->lpszClassName;
  100.  
  101.    // Added elements for Windows 95.
  102.    //...............................
  103.    wcex.cbSize = sizeof(WNDCLASSEX);
  104.    wcex.hIconSm = LoadImage(wcex.hInstance, lpwc->lpszClassName, 
  105.                             IMAGE_ICON, 16, 16,
  106.                             LR_DEFAULTCOLOR );
  107.             
  108.    return RegisterClassEx( &wcex );
  109. }
  110.  
  111.  
  112.  
  113. LRESULT CALLBACK About( HWND hDlg,           
  114.                         UINT message,        
  115.                         WPARAM wParam,       
  116.                         LPARAM lParam)
  117. {
  118.    switch (message) 
  119.    {
  120.        case WM_INITDIALOG: 
  121.                return (TRUE);
  122.  
  123.        case WM_COMMAND:                              
  124.                if (   LOWORD(wParam) == IDOK         
  125.                    || LOWORD(wParam) == IDCANCEL)    
  126.                {
  127.                        EndDialog(hDlg, TRUE);        
  128.                        return (TRUE);
  129.                }
  130.                break;
  131.    }
  132.  
  133.    return (FALSE); 
  134. }
  135.  
  136.  
  137. #define MSG_LEN          1024
  138.  
  139.  
  140. char msg[MSG_LEN+1];
  141. int  nTabStop = 120;
  142. HWND hListBox = NULL;
  143. int  nFrameHeight = 50;
  144.  
  145. VOID OpenAvi(HWND hWnd);
  146. VOID CloseAvi();
  147. VOID Prev(HWND hWnd);
  148. VOID Next(HWND hWnd);
  149. VOID DrawFrame(HWND hWnd);  // calls PaintFrame()
  150. VOID PaintFrame(HWND hWnd, HDC hDC);  // called by DrawFrame and WM_PAINT
  151. VOID DisplayStats(HWND hWnd);
  152.  
  153.  
  154. LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  155. {
  156.    switch( uMsg )
  157.    {
  158.       case WM_CREATE :
  159.               // initialize the AVI library DLL
  160.               //...............................
  161.  
  162.               AVIFileInit();
  163.  
  164.               // Create ListBox
  165.               //...............
  166.  
  167.               hListBox = CreateWindow( "LISTBOX", "",    
  168.                                        WS_CHILD | LBS_NOTIFY | 
  169.                                        WS_VSCROLL | WS_BORDER | 
  170.                                        WS_VISIBLE | LBS_NOINTEGRALHEIGHT |
  171.                                        LBS_USETABSTOPS, 
  172.                                        0, 0, 
  173.                                        0, 0,  
  174.                                        hWnd,              
  175.                                        (HMENU)101,              
  176.                                        hInst,         
  177.                                        NULL );
  178.  
  179.               SendMessage(hListBox, LB_SETTABSTOPS, 1, (LPARAM)&nTabStop);
  180.  
  181.               OpenAvi(hWnd);
  182.               break;
  183.  
  184.       case WM_SIZE :
  185.               MoveWindow(hListBox, 0, nFrameHeight+1, 
  186.                          LOWORD(lParam), 
  187.                          HIWORD(lParam)-nFrameHeight-1, TRUE);
  188.               break;
  189.  
  190.       case WM_COMMAND :
  191.               switch( LOWORD(wParam) )
  192.               {
  193.                  case IDM_PREV:
  194.                         Prev(hWnd);
  195.                         break;
  196.  
  197.                  case IDM_NEXT:
  198.                         Next(hWnd);
  199.                         break;
  200.  
  201.                  case IDM_ABOUT :
  202.                         DialogBox( hInst, "AboutBox", hWnd, About );
  203.                         break;
  204.  
  205.                  case IDM_EXIT :
  206.                         DestroyWindow( hWnd );
  207.                         break;
  208.               }
  209.               break;
  210.  
  211.       case WM_PAINT:
  212.               {
  213.                  HDC         hDC;
  214.                  PAINTSTRUCT ps;
  215.  
  216.                  hDC = BeginPaint(hWnd, &ps);
  217.                  
  218.                  if (hDC)
  219.                      PaintFrame(hWnd, hDC);
  220.  
  221.                  EndPaint(hWnd, &ps);
  222.               }
  223.               break;
  224.  
  225.       case WM_DESTROY :
  226.               // release the AVI library DLL
  227.               //............................
  228.  
  229.               CloseAvi();
  230.  
  231.               AVIFileExit();
  232.  
  233.               PostQuitMessage(0);
  234.               break;
  235.  
  236.       default :
  237.             return( DefWindowProc( hWnd, uMsg, wParam, lParam ) );
  238.    }
  239.  
  240.    return(0L);               
  241. }
  242.  
  243. /*****************************************************************************
  244. *  Global variables
  245. *
  246. *
  247. *
  248. ******************************************************************************/
  249.  
  250. HRESULT    rc;
  251.  
  252. LPCTSTR    lpszInputFilename = "Large.avi";
  253.  
  254. PAVIFILE   pAviIn            = NULL;
  255. PAVISTREAM pAudioStream      = NULL;
  256. PAVISTREAM pVideoStream      = NULL;
  257. PGETFRAME  pVideoFrame       = NULL;
  258. HDRAWDIB   hDrawDibDC        = NULL;
  259.  
  260. LONG       nFrame;
  261.  
  262. /*****************************************************************************
  263. *  OpenAvi
  264. *
  265. *
  266. *
  267. ******************************************************************************/
  268.  
  269. VOID OpenAvi(HWND hWnd)
  270. {
  271.    LONG          i;
  272.    AVIFILEINFO   pFileInfo;
  273.    PAVISTREAM    pAviStream;
  274.    AVISTREAMINFO StreamInfo;
  275.  
  276.    // open input AVI file
  277.    //....................
  278.  
  279.    rc = AVIFileOpen(&pAviIn, lpszInputFilename, OF_READ, NULL);
  280.  
  281.    if (rc) // if error
  282.    {
  283.        MessageBox(hWnd, "Error opening AVI file.",
  284.                   NULL, MB_OK);
  285.        return;
  286.    }
  287.  
  288.    // get input AVI file info
  289.    //........................
  290.  
  291.    pFileInfo.dwStreams = 0L;
  292.  
  293.    rc = AVIFileInfo(pAviIn, &pFileInfo, sizeof(AVIFILEINFO));
  294.  
  295.    // find video stream
  296.    //.................
  297.  
  298.    for (i = 0; i < (LONG)pFileInfo.dwStreams; i++) 
  299.    { 
  300.       rc = AVIFileGetStream(pAviIn, &pAviStream, 0L, i);
  301.        
  302.       if (rc) 
  303.         break;
  304.  
  305.       rc = AVIStreamInfo(pAviStream, &StreamInfo, sizeof(AVISTREAMINFO)); 
  306.  
  307.       if (rc)
  308.           continue;
  309.  
  310.       if (StreamInfo.fccType == streamtypeVIDEO)
  311.       {
  312.           pVideoStream = pAviStream;
  313.           AVIStreamAddRef(pVideoStream);
  314.           nFrameHeight = StreamInfo.rcFrame.bottom - StreamInfo.rcFrame.top;
  315.       }
  316.       else if (StreamInfo.fccType == streamtypeAUDIO)
  317.       {
  318.           pAudioStream = pAviStream;
  319.           AVIStreamAddRef(pAudioStream);
  320.       }
  321.     }
  322.  
  323.     // draw first frame
  324.     //.................
  325.     
  326.     if (pVideoStream)
  327.     {
  328.         pVideoFrame  = AVIStreamGetFrameOpen(pVideoStream, 
  329.                           (LPBITMAPINFOHEADER)AVIGETFRAMEF_BESTDISPLAYFMT);
  330.         hDrawDibDC   = DrawDibOpen();
  331.           
  332.         
  333.  
  334.         // jump into middle of stream at a key frame position
  335.  
  336.         nFrame = AVIStreamFindSample(pVideoStream, 
  337.                                      AVIStreamLength(pVideoStream) / 2 +
  338.                                      AVIStreamStart(pVideoStream),
  339.                                      FIND_NEXT | FIND_KEY);
  340.           
  341.         DrawFrame(hWnd);
  342.         DisplayStats(hWnd);
  343.     }
  344.     else
  345.         MessageBox(hWnd, "Video stream not found!", NULL, MB_OK); 
  346. }
  347.  
  348. /*****************************************************************************
  349. *  CloseAvi
  350. *
  351. *
  352. *
  353. ******************************************************************************/
  354.  
  355. VOID CloseAvi()
  356. {
  357.    // release resources allocated during video decompression
  358.    //.......................................................
  359.  
  360.    if (pVideoFrame)
  361.    {
  362.        AVIStreamGetFrameClose(pVideoFrame);
  363.        pVideoFrame = NULL;
  364.    }
  365.  
  366.    // release DrawDib stuff
  367.    //......................
  368.  
  369.    DrawDibClose(hDrawDibDC);
  370.    
  371.    // release AVI streams
  372.    //....................
  373.  
  374.    if (pVideoStream)
  375.        AVIStreamRelease(pVideoStream);
  376.  
  377.    if (pAudioStream)
  378.        AVIStreamRelease(pAudioStream);
  379.  
  380.    // close AVI file
  381.    //...............
  382.  
  383.    AVIFileRelease(pAviIn);
  384. }
  385.  
  386. /*****************************************************************************
  387. *  Prev
  388. *
  389. *
  390. *
  391. ******************************************************************************/
  392.  
  393. VOID Prev(HWND hWnd)
  394. {
  395.    if (nFrame > AVIStreamStart(pVideoStream))
  396.    {
  397.        nFrame--;
  398.        DisplayStats(hWnd);
  399.        DrawFrame(hWnd);
  400.    }
  401. }
  402.  
  403. /*****************************************************************************
  404. *  Next
  405. *
  406. *
  407. *
  408. ******************************************************************************/
  409.  
  410. VOID Next(HWND hWnd)
  411. {
  412.    if (nFrame < AVIStreamEnd(pVideoStream))
  413.    {
  414.        nFrame++;
  415.        DisplayStats(hWnd);
  416.        DrawFrame(hWnd);
  417.    }
  418. }
  419.  
  420. /*****************************************************************************
  421. *  DrawFrame
  422. *
  423. *
  424. *
  425. ******************************************************************************/
  426.  
  427. VOID DrawFrame(HWND hWnd)
  428. {
  429.    HDC hDC;
  430.    
  431.    hDC = GetDC(hWnd);
  432.  
  433.    PaintFrame(hWnd, hDC);
  434.  
  435.    ReleaseDC(hWnd, hDC);
  436. }
  437.  
  438. /*****************************************************************************
  439. *  PaintFrame
  440. *
  441. *
  442. *
  443. ******************************************************************************/
  444.  
  445. VOID PaintFrame(HWND hWnd, HDC hDC)
  446. {
  447.    AVISTREAMINFO      StreamInfo;
  448.    LPBITMAPINFOHEADER lpBitmapInfoHeader = NULL;
  449.    
  450.    // Draw video frame DIB
  451.    //.....................
  452.  
  453.    AVIStreamInfo(pVideoStream, &StreamInfo, sizeof(AVISTREAMINFO));
  454.  
  455.    lpBitmapInfoHeader = AVIStreamGetFrame(pVideoFrame, nFrame);
  456.  
  457.    DrawDibDraw(hDrawDibDC, hDC,
  458.                  StreamInfo.rcFrame.left, 
  459.                  StreamInfo.rcFrame.top,
  460.                  StreamInfo.rcFrame.right  - StreamInfo.rcFrame.left,
  461.                  StreamInfo.rcFrame.bottom - StreamInfo.rcFrame.top,
  462.                  lpBitmapInfoHeader, NULL,
  463.                  0, 0, -1, -1,
  464.                  0);
  465. }
  466.  
  467. /*****************************************************************************
  468. *  DisplayStats
  469. *
  470. *  Note: the term "Frame" refers to a video sample
  471. *
  472. ******************************************************************************/
  473.  
  474. #define Display(msg)    SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM)msg)
  475.  
  476. VOID DisplayStats(HWND hWnd)
  477. {
  478.    LONG nTime = AVIStreamSampleToTime(pVideoStream, nFrame);
  479.  
  480.    SendMessage(hListBox, LB_RESETCONTENT, 0, 0);
  481.  
  482.    // current frame/time
  483.    //......................
  484.  
  485.    sprintf(msg, "Position:\t Frame: %ld Seconds: %ld.%03ld Key frame: %s", 
  486.            nFrame, 
  487.            nTime / 1000, 
  488.            nTime % 1000,
  489.            (AVIStreamIsKeyFrame(pVideoStream, nFrame) ? "Yes" : "No"));
  490.    Display(msg);
  491.  
  492.    if (pAudioStream)
  493.    {
  494.        LONG nBeg = AVIStreamSampleToSample(pAudioStream, pVideoStream, nFrame);
  495.        LONG nEnd = AVIStreamSampleToSample(pAudioStream, pVideoStream, nFrame+1);
  496.  
  497.        sprintf(msg, "Corresponding audio samples:\t %ld through %ld", 
  498.                nBeg, nEnd-1);
  499.        Display(msg);
  500.    }
  501.  
  502.    // prev key frame (frame/time)
  503.    //............................
  504.  
  505.    Display("");
  506.  
  507.    sprintf(msg, "Previous key frame:\t Frame: %ld Seconds: %ld.%03ld", 
  508.            AVIStreamPrevKeyFrame(pVideoStream, nFrame), 
  509.            AVIStreamPrevKeyFrameTime(pVideoStream, nTime) / 1000, 
  510.            AVIStreamPrevKeyFrameTime(pVideoStream, nTime) % 1000);
  511.    Display(msg);
  512.    
  513.    // nearest key frame (frame/time)
  514.    //...............................
  515.  
  516.    sprintf(msg, "Nearest key frame:\t Frame: %ld Seconds: %ld.%03ld", 
  517.            AVIStreamNearestKeyFrame(pVideoStream, nFrame), 
  518.            AVIStreamNearestKeyFrameTime(pVideoStream, nTime) / 1000, 
  519.            AVIStreamNearestKeyFrameTime(pVideoStream, nTime) % 1000);
  520.    Display(msg);
  521.    
  522.    // next key frame (frame/time)
  523.    //............................
  524.  
  525.    sprintf(msg, "Next key frame:\t Frame: %ld Seconds: %ld.%03ld", 
  526.            AVIStreamNextKeyFrame(pVideoStream, nFrame), 
  527.            AVIStreamNextKeyFrameTime(pVideoStream, nTime) / 1000, 
  528.            AVIStreamNextKeyFrameTime(pVideoStream, nTime) % 1000);
  529.    Display(msg);
  530.  
  531.    // prev sample (frame/time)
  532.    //.........................
  533.  
  534.    Display("");
  535.  
  536.    sprintf(msg, "Previous sample:\t Frame: %ld Seconds: %ld.%03ld", 
  537.            AVIStreamPrevSample(pVideoStream, nFrame), 
  538.            AVIStreamPrevSampleTime(pVideoStream, nTime) / 1000, 
  539.            AVIStreamPrevSampleTime(pVideoStream, nTime) % 1000);
  540.    Display(msg);
  541.    
  542.    // nearest sample (frame/time)
  543.    //............................
  544.  
  545.    sprintf(msg, "Nearest sample:\t Frame: %ld Seconds: %ld.%03ld", 
  546.            AVIStreamNearestSample(pVideoStream, nFrame), 
  547.            AVIStreamNearestSampleTime(pVideoStream, nTime) / 1000, 
  548.            AVIStreamNearestSampleTime(pVideoStream, nTime) % 1000);
  549.    Display(msg);
  550.    
  551.    // next sample (frame/time)
  552.    //.........................
  553.  
  554.    sprintf(msg, "Next sample:\t Frame: %ld Seconds: %ld.%03ld", 
  555.            AVIStreamNextSample(pVideoStream, nFrame), 
  556.            AVIStreamNextSampleTime(pVideoStream, nTime) / 1000, 
  557.            AVIStreamNextSampleTime(pVideoStream, nTime) % 1000);
  558.    Display(msg);
  559.  
  560.    // begin frame/time
  561.    //.................
  562.  
  563.    Display("");  // blank line
  564.  
  565.    sprintf(msg, "Begin Time:\t Frame: %ld Seconds: %ld.%03ld",
  566.               AVIStreamStart(pVideoStream),
  567.               AVIStreamStartTime(pVideoStream) / 1000,
  568.               AVIStreamStartTime(pVideoStream) % 1000);
  569.    Display(msg);
  570.  
  571.    // end frame/time
  572.    //...............
  573.  
  574.    sprintf(msg, "End Time:\t Frame: %ld Seconds: %ld.%03ld",
  575.               AVIStreamEnd(pVideoStream),
  576.               AVIStreamEndTime(pVideoStream) / 1000,
  577.               AVIStreamEndTime(pVideoStream) % 1000);
  578.    Display(msg);
  579.  
  580.    // stream length frames/time
  581.    //..........................
  582.  
  583.    sprintf(msg, "Length:\t Frames: %ld Seconds: %ld.%03ld",
  584.               AVIStreamLength(pVideoStream),
  585.               AVIStreamLengthTime(pVideoStream) / 1000,
  586.               AVIStreamLengthTime(pVideoStream) % 1000);
  587.    Display(msg);
  588. }
  589.